using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using RNChessBoardCommonTypes;
//---------------------------------------------------------------------------//
//																			 //
//			r  n  C  h  e  s  s  B  o  a  r  d  C  o  n  t  r  o  l			 //
//			=======================================================			 //
//						  (c) 2003 Chris R. Chapman							 //
//																			 //
//	Version:		1.0	Full												 //
//  Date:			May 2003												 //
//  Author:			Chris R. Chapman (chris@chapmanconsulting.ca)			 //
//  Description:	A chessboard GUI written in 100% .Net/C#, featuring		 //
//					a resizable board with adjustable colors and configurable//
//					images for pieces, as well as events for capturing player//
//					movement and illegal moves.								 //
//																			 //
//																			 //
// LICENSING:		Can be freely distributed and used as long as the		 //
//					following criteria are met:								 //
//																			 //
//					1) All copyright notices are kept intact;				 //
//					2) Product is not for commercial resale;				 //
//					3) Product is NOT used in conjunction with ANY GPLed or  //
//					   FSF software.  I cannot abide by their philosophies.  //
//					4) Credit for the control to me is made in some			 //
//					   conspicuous fashion, like an About box.				 //
//---------------------------------------------------------------------------//
namespace RNChessBoard
{
	/// <summary>
	/// Defines the dialog window used for soliciting a pawn promotion piece
	/// from a player.
	/// </summary>
	public class frmPawnPromotion : System.Windows.Forms.Form
	{
		#region Form Fields and Variables
		private System.Windows.Forms.Button cmdKnight;
		private System.Windows.Forms.Button cmdBishop;
		private System.Windows.Forms.Button cmdRook;
		private System.Windows.Forms.Button cmdQueen;
		private System.ComponentModel.IContainer components;

		private int _promotedPiece;
		private ImageList _chessPiecesImageList = null;
		private Image _chessPieceSet = null;
		private PlayerTurn _sideToPromote;
		private Rectangle _knightRect = new Rectangle(33,0,32,32);
		private Rectangle _bishopRect = new Rectangle(65,0,32,32);
		private Rectangle _rookRect = new Rectangle(97,0,32,32);
		private System.Windows.Forms.Label label1;
		private Rectangle _queenRect = new Rectangle(129,0,32,32);
		private int _frameWidth = 4;
		#endregion

		#region Property Accessors
		/// <summary>
		/// Gets the promoted piece the user has selected.
		/// </summary>
		public int PromotedPiece
		{
			get { return _promotedPiece; }
		}

		/// <summary>
		/// Get/Set the ImageList for displaying the chesspieces for pawn promotion buttons.
		/// </summary>
		/// <remarks>
		/// This ImageList must contain images that conform to the specification for the RNChessBoardControl, ie
		/// two 192 x 32 pixel image strips for the black and white chess pieces.
		/// </remarks>
		public ImageList ChessPiecesImageList
		{
			get { return _chessPiecesImageList; }
			set { _chessPiecesImageList = value; }
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Instantiate a new pawn promotion window.
		/// </summary>
		public frmPawnPromotion()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
		}

		/// <summary>
		/// Instantiate a new pawn promotion window using a provided ImageList to populate the buttons.
		/// </summary>
		/// <param name="chessPieceImageList">ImageList object that contains 192 x 32 pixel bitmap images for the pieces.</param>
		public frmPawnPromotion(ImageList chessPieceImageList)
		{
			InitializeComponent();
			_chessPiecesImageList = chessPieceImageList;
		}
		#endregion

		#region Base Class Overrides and Setup
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		
		/// <summary>
		/// Overridden;  draw a frame around the form window and then pass control
		/// back to the base class for painting.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPaint(PaintEventArgs e)
		{
            DrawFrame();
			base.OnPaint (e);
		}


		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.cmdKnight = new System.Windows.Forms.Button();
			this.cmdBishop = new System.Windows.Forms.Button();
			this.cmdRook = new System.Windows.Forms.Button();
			this.cmdQueen = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// cmdKnight
			// 
			this.cmdKnight.BackColor = System.Drawing.Color.Tan;
			this.cmdKnight.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.cmdKnight.Location = new System.Drawing.Point(20, 24);
			this.cmdKnight.Name = "cmdKnight";
			this.cmdKnight.Size = new System.Drawing.Size(48, 48);
			this.cmdKnight.TabIndex = 0;
			this.cmdKnight.Tag = "";
			this.cmdKnight.Click += new System.EventHandler(this.cmdKnight_Click);
			// 
			// cmdBishop
			// 
			this.cmdBishop.BackColor = System.Drawing.Color.Beige;
			this.cmdBishop.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.cmdBishop.Location = new System.Drawing.Point(76, 24);
			this.cmdBishop.Name = "cmdBishop";
			this.cmdBishop.Size = new System.Drawing.Size(48, 48);
			this.cmdBishop.TabIndex = 1;
			this.cmdBishop.Click += new System.EventHandler(this.cmdBishop_Click);
			// 
			// cmdRook
			// 
			this.cmdRook.BackColor = System.Drawing.Color.Tan;
			this.cmdRook.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.cmdRook.Location = new System.Drawing.Point(132, 24);
			this.cmdRook.Name = "cmdRook";
			this.cmdRook.Size = new System.Drawing.Size(48, 48);
			this.cmdRook.TabIndex = 2;
			this.cmdRook.Click += new System.EventHandler(this.cmdRook_Click);
			// 
			// cmdQueen
			// 
			this.cmdQueen.BackColor = System.Drawing.Color.Beige;
			this.cmdQueen.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.cmdQueen.Location = new System.Drawing.Point(188, 24);
			this.cmdQueen.Name = "cmdQueen";
			this.cmdQueen.Size = new System.Drawing.Size(48, 48);
			this.cmdQueen.TabIndex = 3;
			this.cmdQueen.Click += new System.EventHandler(this.cmdQueen_Click);
			// 
			// label1
			// 
			this.label1.BackColor = System.Drawing.Color.Beige;
			this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.label1.ForeColor = System.Drawing.SystemColors.ControlText;
			this.label1.Location = new System.Drawing.Point(20, 6);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(216, 16);
			this.label1.TabIndex = 4;
			this.label1.Text = "P R O M O T E  P A W N  T O :";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// frmPawnPromotion
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.BackColor = System.Drawing.Color.SaddleBrown;
			this.ClientSize = new System.Drawing.Size(256, 80);
			this.ControlBox = false;
			this.Controls.Add(this.label1);
			this.Controls.Add(this.cmdQueen);
			this.Controls.Add(this.cmdRook);
			this.Controls.Add(this.cmdBishop);
			this.Controls.Add(this.cmdKnight);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
			this.Name = "frmPawnPromotion";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "Select piece for promotion:";
			this.Load += new System.EventHandler(this.frmPawnPromotion_Load);
			this.ResumeLayout(false);

		}
		#endregion

		#endregion

		#region Show Methods
		/// <summary>
		/// Displays the promotion pieces for a given side.
		/// </summary>
		/// <param name="sideToPromote">Player side to show promotion pieces.</param>
		/// <param name="returnedPiece">Reference to a chess piece value that will be updated once the piece is selected.</param>
		public void ShowDialog(System.Windows.Forms.IWin32Window owner, PlayerTurn sideToPromote)
		{
			if(_chessPiecesImageList==null)
			{
				throw new BadImageFormatException("The ImageList for the chess pieces has not been set.");
			}
			if(_chessPiecesImageList.Images.Count < 2)
			{
				throw new ApplicationException("The ImageList for the chess pieces does not contain two bitmaps for the white and black pieces.");
			}

			_sideToPromote = sideToPromote;
			if(sideToPromote==PlayerTurn.Black)
			{
				_chessPieceSet = _chessPiecesImageList.Images[0];
			}
			else
			{
				_chessPieceSet = _chessPiecesImageList.Images[1];
			}

			base.ShowDialog(owner);
		}
		#endregion

		#region Image Loading Methods
		/// <summary>
		/// Loads requisite image into the object from a given bounding rectangle.
		/// </summary>
		/// <param name="chessPieceImage"></param>
		/// <param name="pieceRect"></param>
		protected Bitmap LoadImage(Rectangle pieceRect)
		{
			Bitmap pieceBitmap = new Bitmap(32,32,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
			Graphics pieceDC = Graphics.FromImage(pieceBitmap);
			Rectangle destRect = new Rectangle(0,0,32,32);

			pieceDC.DrawImage(_chessPieceSet,destRect,pieceRect,System.Drawing.GraphicsUnit.Pixel);
			pieceDC.Dispose();
			
			return pieceBitmap;
		}
		#endregion

		#region Button Click Handlers
		/// <summary>
		/// Event handler triggered when the Knight promotion button is pressed
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void cmdKnight_Click(object sender, System.EventArgs e)
		{
			_promotedPiece = (int)cmdKnight.Tag;
			this.Close();
		}

		/// <summary>
		/// Event handler triggered when the Bishop promotion button is pressed
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void cmdBishop_Click(object sender, System.EventArgs e)
		{
			_promotedPiece = (int)cmdBishop.Tag;
			this.Close();
		}
		
		/// <summary>
		/// Event handler triggered when the Rook promotion button is pressed
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void cmdRook_Click(object sender, System.EventArgs e)
		{
			_promotedPiece = (int)cmdRook.Tag;
			this.Close();
		}

		/// <summary>
		/// Event handler triggered when the Queen promotion button is pressed
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void cmdQueen_Click(object sender, System.EventArgs e)
		{
			_promotedPiece = (int)cmdQueen.Tag;
			this.Close();
		}
		#endregion
		
		#region Form Event Handlers
		private void frmPawnPromotion_Load(object sender, System.EventArgs e)
		{
			// Load up button images and set return values for piece type
			cmdKnight.Image = LoadImage(_knightRect);
			cmdKnight.Tag = _sideToPromote == PlayerTurn.Black ? -ChessPieceDefinition.KNIGHT : ChessPieceDefinition.KNIGHT;

			cmdBishop.Image = LoadImage(_bishopRect);
			cmdBishop.Tag = _sideToPromote == PlayerTurn.Black ? -ChessPieceDefinition.BISHOP : ChessPieceDefinition.BISHOP;

			cmdRook.Image = LoadImage(_rookRect);
			cmdRook.Tag = _sideToPromote == PlayerTurn.Black ? -ChessPieceDefinition.ROOK : ChessPieceDefinition.ROOK;

			cmdQueen.Image = LoadImage(_queenRect);
			cmdQueen.Tag = _sideToPromote == PlayerTurn.Black ? -ChessPieceDefinition.QUEEN : ChessPieceDefinition.QUEEN;
		}
		#endregion
		
		#region Graphics Methods
		/// <summary>
		/// Draw a border around the form.
		/// </summary>
		private void DrawFrame()
		{
			int nFrameH;
			int nFrameW;

			Graphics gObj = this.CreateGraphics();
			//nFrameH = nFrameW = this.Height - 1;
			nFrameH = this.Height;
			nFrameW = this.Width;
			Rectangle rBoardFrame = new Rectangle(0,0,nFrameW,nFrameH);
			Pen pn = new Pen(Color.Black,_frameWidth);
			gObj.DrawRectangle(pn,rBoardFrame);
			gObj.Dispose();
		}
		#endregion
	}
}
